package com.saret.crawler.parser;


import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.saret.crawler.type.GWord;
import com.saret.crawler.type.GWordImpl;
import com.saret.crawler.type.GWordList;
import com.saret.utils.Consumer;
import com.saret.utils.FileLocator;
import com.saret.utils.UtfFileHandle;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Collection;

/**
 * User: biniam.gebremichael
 * Date: 2/3/11
 */
public abstract class TxtParser implements WordListParser {
    final File wordListFile;
    final GWordList wordList;
    final GWordList errorList = new GWordList();


    @Inject
    public TxtParser(@Named("saret.crawler.current.wordlList") String wordListFile) {
        this.wordListFile = FileLocator.getConfigFile(wordListFile.split("/"));
        this.wordList = new GWordList(this.wordListFile);

    }

    protected abstract String wordVisitor(String word);

    protected abstract GWordList wordListVisitor(GWordList word, File file);


    public void start() {
        File completedDir = FileLocator.getCompletedDir();
        for (File file : completedDir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith("txt");
            }
        })) {
            if (file.isDirectory()) {
                readDir(file);
            } else {
                wordList.put(getGWords(file).getgWordMap());
            }
        }
            UtfFileHandle.write(wordListFile, getWordList().toArray());

    }

    @Override
    public GWordList getGWords(final File file) {

        final GWordList fileWordList = new GWordList();
        try {
            UtfFileHandle.readFile(file, new Consumer<String>() {
                @Override
                public void consume(String line) {
                    String trimedWord;
                    for (String word : line.split(" ")) {
                        if ((trimedWord = wordVisitor(word)) != null) {
                            fileWordList.put(new GWordImpl(trimedWord, null));
                            //  System.out.println("word = " + trimedWord);
                        } else {
                            errorList.put(new GWordImpl(word, null));
                        }
                    }
                }
            });
        } catch (IOException e) {
            System.err.println("error at " + file);
        }
        return wordListVisitor(fileWordList, file);

    }

    public Collection<GWord> getWordList() {
        return wordList.getSortedGWord();
    }


    public Collection<GWord> getErrorList() {
        return errorList.getgWordMap();
    }


    public void readDir(File dir) {
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                readDir(file);
            } else {
                getGWords(file);
            }
        }
    }

}
